home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #3 / Amiga Plus CD - 1997 - No. 03.iso / pd / programmierung / vbcc / statements.c < prev    next >
C/C++ Source or Header  |  1997-01-29  |  29KB  |  844 lines

  1. /*  $VER: vbcc (statements.c) V0.4  */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int cont_label=0;
  8. int test_assignment(struct Typ *,np);
  9.  
  10. #define cr()
  11. #ifndef cr
  12. void cr(void)
  13. /*  tested Registerbelegung */
  14. {
  15.     int i;
  16.     for(i=0;i<=MAXR;i++)
  17.         if(regs[i]!=regsa[i]) {error(149,regnames[i]);regs[i]=regsa[i];}
  18. }
  19. #endif
  20. void statement(void)
  21. /*  bearbeitet ein statement                                    */
  22. {
  23.     char *merk;
  24.     cr();
  25.     killsp();
  26.     if(*s=='{'){
  27.         enter_block();
  28.         if(nesting>0) local_offset[nesting]=local_offset[nesting-1];
  29.         compound_statement();leave_block();return;}
  30.     merk=s;
  31.     cpbez(buff,0);
  32.     if(!strcmp("if",buff)){if_statement();return;}
  33.     if(!strcmp("switch",buff)){switch_statement();return;}
  34.     if(!strcmp("for",buff)){for_statement();return;}
  35.     if(!strcmp("while",buff)){while_statement();return;}
  36.     if(!strcmp("do",buff)){do_statement();return;}
  37.     if(!strcmp("goto",buff)){goto_statement();return;}
  38.     if(!strcmp("continue",buff)){continue_statement();return;}
  39.     if(!strcmp("break",buff)){break_statement();return;}
  40.     if(!strcmp("return",buff)){return_statement();return;}
  41.     if(!strcmp("case",buff)){labeled_statement();return;}
  42.     killsp();if(*s==':'){labeled_statement();return;}
  43.     /*  fehlt Aufruf der anderen statements */
  44.     s=merk;
  45.     expression_statement();
  46. }
  47. void labeled_statement(void)
  48. /*  bearbeitet labeled_statement                                */
  49. {
  50.     struct llist *lp;int def=0;
  51.     nocode=0;
  52.     if(*s==':'){
  53.         s++;
  54.         if(!*buff){error(130);return;}
  55.         if(!strcmp("default",buff)){def=1;lp=0;} else lp=find_label(buff);
  56.         if(lp&&lp->flags&LABELDEFINED){error(131,buff);return;}
  57.         if(!lp) lp=add_label(buff);
  58.         lp->flags|=LABELDEFINED;
  59.         lp->switch_count=0;
  60.         if(def){
  61.             if(switch_act==0) error(150);
  62.             lp->flags|=LABELDEFAULT;
  63.             lp->switch_count=switch_act;
  64.         }
  65.         gen_label(lp->label);
  66.         afterlabel=0;
  67.     }else{
  68.         /*  case    */
  69.         np tree;struct llist *lp;
  70.         tree=expression();
  71.         killsp();
  72.         if(*s==':'){s++;killsp();} else error(70);
  73.         if(!switch_count){
  74.             error(132);
  75.         }else{
  76.             if(!tree||!type_expression(tree)){
  77.             }else{
  78.                 if(tree->flags!=CEXPR||tree->sidefx){
  79.                     error(133);
  80.                 }else{
  81.                     if((tree->ntyp->flags&15)<CHAR||(tree->ntyp->flags&15)>LONG){
  82.                         error(134);
  83.                     }else{
  84.                         lp=add_label(empty);
  85.                         lp->flags=LABELDEFINED;
  86.                         lp->switch_count=switch_act;
  87.                         eval_constn(tree);
  88.                         if(switch_typ==CHAR) lp->val.vchar=vchar;
  89.                         if(switch_typ==(UNSIGNED|CHAR)) lp->val.vuchar=vuchar;
  90.                         if(switch_typ==SHORT) lp->val.vshort=vshort;
  91.                         if(switch_typ==(UNSIGNED|SHORT)) lp->val.vushort=vushort;
  92.                         if(switch_typ==INT) lp->val.vint=vint;
  93.                         if(switch_typ==(UNSIGNED|INT)) lp->val.vuint=vuint;
  94.                         if(switch_typ==LONG) lp->val.vlong=vlong;
  95.                         if(switch_typ==(UNSIGNED|LONG)) lp->val.vulong=vulong;
  96.                         if(switch_typ==POINTER) lp->val.vpointer=vpointer;
  97.                         gen_label(lp->label);
  98.                     }
  99.                 }
  100.             }
  101.         }
  102.         if(tree) free_expression(tree);
  103.     }
  104.     cr();
  105.     killsp();
  106.     if(*s!='}') statement();
  107. }
  108. void if_statement(void)
  109. /*  bearbeitet if_statement                                     */
  110. {
  111.     int ltrue,lfalse,lout,cexpr,cm;char *merk,buff[MAXI];
  112.     np tree;struct IC *new;
  113.     killsp(); if(*s=='(') s++; else error(151);
  114.     killsp();cm=nocode;
  115.     tree=expression();
  116.     if(!tree) {error(135);
  117.     }else{
  118.         ltrue=++label;lfalse=++label;
  119.         if(type_expression(tree)){
  120.             tree=makepointer(tree);
  121.             if(!arith(tree->ntyp->flags&15)&&(tree->ntyp->flags&15)!=POINTER)
  122.                 {error(136);
  123.             }else{
  124.                 if(tree->flags==ASSIGN) error(164);
  125.                 gen_IC(tree,ltrue,lfalse);
  126.                 if(tree->flags==CEXPR){
  127.                     eval_const(&tree->val,tree->ntyp->flags&31);
  128.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0))&&zuleqto(vulong,ul2zul(0UL))) cexpr=2; else cexpr=1;
  129.                 }else cexpr=0;
  130.                 if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  131.                 if(tree->o.flags&&!cexpr){
  132.                     new=mymalloc(ICS);
  133.                     new->code=TEST;
  134.                     new->q1=tree->o;
  135.                     new->q2.flags=new->z.flags=0;
  136.                     new->typf=tree->ntyp->flags;
  137.                     add_IC(new);
  138.                     new=mymalloc(ICS);
  139.                     new->code=BEQ;
  140.                     new->typf=lfalse;
  141.                     add_IC(new);
  142.                 }
  143.                 if(cexpr==2){
  144.                     new=mymalloc(ICS);
  145.                     new->code=BRA;
  146.                     new->typf=lfalse;
  147.                     add_IC(new);
  148.                 }
  149.             }
  150.         }
  151.         free_expression(tree);
  152.     }
  153.     killsp(); if(*s==')') s++; else error(59);
  154.     if(cexpr==2) nocode=1;
  155.     if(!cexpr&&!tree->o.flags) gen_label(ltrue);
  156.     statement();
  157.     killsp();
  158.     merk=s;
  159.     cpbez(buff,0);
  160.     if(strcmp("else",buff)) {s=merk;nocode=cm;if(cexpr!=1) gen_label(lfalse);return;}
  161.     lout=++label;
  162.     if(cexpr!=2){
  163.         new=mymalloc(ICS);
  164.         new->code=BRA;
  165.         new->typf=lout;
  166.         add_IC(new);
  167.     }
  168.     if(cexpr!=1) {nocode=cm;gen_label(lfalse);}
  169.     if(cexpr==1) nocode=1; else nocode=cm;
  170.     statement();
  171.     nocode=cm;
  172.     if(cexpr!=2) gen_label(lout);
  173.     cr();
  174. }
  175. void switch_statement(void)
  176. /*  bearbeitet switch_statement                                 */
  177. {
  178.     np tree;int merk_typ,merk_count,merk_break;
  179.     struct IC *merk_fic,*merk_lic,*new;struct llist *lp,*l1,*l2;
  180.     killsp();
  181.     if(*s=='('){s++;killsp();} else error(151);
  182.     tree=expression(); killsp();
  183.     if(*s==')'){s++;killsp();} else error(59);
  184.     merk_typ=switch_typ;merk_count=switch_act;merk_break=break_label;
  185.     if(!tree){
  186.         error(137);
  187.     }else{
  188.         if(!type_expression(tree)){
  189.         }else{
  190.             if((tree->ntyp->flags&15)<CHAR||(tree->ntyp->flags&15)>LONG){
  191.                 error(138);
  192.             }else{
  193.                 int m1,m2,m3,def=0,rm,minflag;
  194.                 zlong l,ml,s;zulong ul,mul,us;
  195.                 if(tree->flags==ASSIGN) error(164);
  196.                 m3=break_label=++label;m1=switch_act=++switch_count;
  197.                 m2=switch_typ=tree->ntyp->flags&31;
  198.                 gen_IC(tree,0,0);
  199.                 if((tree->o.flags&(DREFOBJ|SCRATCH))!=SCRATCH){
  200.                     new=mymalloc(ICS);
  201.                     new->code=ASSIGN;
  202.                     new->q1=tree->o;
  203.                     new->q2.flags=0;
  204.                     new->q2.val.vlong=sizetab[m2&15];
  205.                     get_scratch(&new->z,m2,0);
  206.                     new->typf=m2;
  207.                     tree->o=new->z;
  208.                     add_IC(new);
  209.                 }
  210.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){
  211.                     int r=tree->o.reg;
  212.                     rm=regs[r];
  213.                     regs[r]=regsa[r];
  214.                 }
  215.                 merk_fic=first_ic;merk_lic=last_ic;
  216.                 first_ic=last_ic=0;
  217.                 statement();
  218.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)) regs[tree->o.reg]=rm;
  219.                 minflag=0;s=l2zl(0L);us=ul2zul(0UL);
  220.                 for(l1=first_llist;l1;l1=l1->next){
  221.                     if(l1->switch_count!=m1) continue;
  222.                     if(l1->flags&LABELDEFAULT){
  223.                         if(def) error(139);
  224.                         def=l1->label;
  225.                         continue;
  226.                     }
  227.                     lp=0;minflag&=~1;
  228.                     for(l2=first_llist;l2;l2=l2->next){
  229.                         if(l2->switch_count!=m1) continue;
  230.                         if(l2->flags&LABELDEFAULT) continue;
  231.                         eval_const(&l2->val,m2);
  232.                         if(minflag&2){
  233.                             if(m2&UNSIGNED){
  234.                                 if(zulleq(vulong,mul)||zuleqto(vulong,mul)) continue;
  235.                             }else{
  236.                                 if(zlleq(vlong,ml)||zleqto(vlong,ml)) continue;
  237.                             }
  238.                         }
  239.                         if(minflag&1){
  240.                             if(m2&UNSIGNED){
  241.                                 if(!(minflag&4)&&zuleqto(vulong,ul)){ error(201);minflag|=4;}
  242.                                 if(zulleq(vulong,ul)){lp=l2;ul=vulong;}
  243.                             }else{
  244.                                 if(!(minflag&4)&&zleqto(vlong,l)){ error(201);minflag|=4;}
  245.                                 if(zlleq(vlong,l)){lp=l2;l=vlong;}
  246.                             }
  247.                         }else{
  248.                             minflag|=1;
  249.                             l=vlong;
  250.                             ul=vulong;
  251.                             lp=l2;
  252.                         }
  253.                     }
  254.                     if(!lp) continue;
  255.                     ml=l;mul=ul;minflag|=2;
  256.                     if(SWITCHSUBS){
  257.                         new=mymalloc(ICS);
  258.                         new->line=0;
  259.                         new->file=0;
  260.                         new->typf=m2;
  261.                         new->code=SUB;
  262.                         new->q1=tree->o;
  263.                         new->z=tree->o;
  264.                         new->q2.flags=KONST;
  265.                         eval_const(&lp->val,m2);
  266.                         vlong=zlsub(vlong,s);
  267.                         vulong=zulsub(vulong,us);
  268.                         vint=zl2zi(vlong);
  269.                         vshort=zl2zs(vlong);
  270.                         vchar=zl2zc(vlong);
  271.                         vuint=zul2zui(vulong);
  272.                         vushort=zul2zus(vulong);
  273.                         vuchar=zul2zuc(vulong);
  274.                         insert_const2(&new->q2.val,m2);
  275.                         new->q1.am=new->q2.am=new->z.am=0;
  276.                         s=l;us=ul;
  277.                         new->prev=merk_lic;
  278.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  279.                         merk_lic=new;
  280.                         new=mymalloc(ICS);
  281.                         new->line=0;
  282.                         new->file=0;
  283.                         new->typf=m2;
  284.                         new->code=TEST;
  285.                         new->q1=tree->o;
  286.                         new->q2.flags=new->z.flags=0;
  287.                         new->prev=merk_lic;
  288.                         new->q1.am=new->q2.am=new->z.am=0;
  289.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  290.                         merk_lic=new;
  291.                     }else{
  292.                         new=mymalloc(ICS);
  293.                         new->line=0;
  294.                         new->file=0;
  295.                         new->code=COMPARE;
  296.                         new->typf=m2;
  297.                         new->q1=tree->o;
  298.                         new->q2.flags=KONST;
  299.                         new->q2.val=lp->val;
  300.                         new->z.flags=0;
  301.                         new->prev=merk_lic;
  302.                         new->q1.am=new->q2.am=new->z.am=0;
  303.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  304.                         merk_lic=new;
  305.                     }
  306.                     new=mymalloc(ICS);
  307.                     new->line=0;
  308.                     new->file=0;
  309.                     new->code=BEQ;
  310.                     new->typf=lp->label;
  311.                     new->q1.flags=new->q2.flags=new->z.flags=0;
  312.                     new->prev=merk_lic;
  313.                     new->q1.am=new->q2.am=new->z.am=0;
  314.                     merk_lic->next=new;
  315.                     merk_lic=new;
  316.                 }
  317.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){   /* free_reg(tree->o.reg); */
  318.                     new=mymalloc(ICS);
  319.                     new->line=0;
  320.                     new->file=0;
  321.                     new->code=FREEREG;new->typf=0;
  322.                     new->q2.flags=new->z.flags=0;
  323.                     new->q1.flags=REG;
  324.                     new->q1.reg=tree->o.reg;
  325.                     new->prev=merk_lic;
  326.                     new->q1.am=new->q2.am=new->z.am=0;
  327.                     if(merk_lic) merk_lic->next=new; else merk_fic=new;
  328.                     merk_lic=new;
  329.                     regs[tree->o.reg]=regsa[tree->o.reg];
  330.                 }
  331.                 new=mymalloc(ICS);
  332.                 new->line=0;
  333.                 new->file=0;
  334.                 new->code=BRA;
  335.                 if(def) new->typf=def; else new->typf=m3;
  336.                 new->q1.flags=new->q2.flags=new->z.flags=0;
  337.                 if(merk_lic) merk_lic->next=new; else merk_fic=new;
  338.                 new->prev=merk_lic;
  339.                 first_ic->prev=new;
  340.                 new->next=first_ic;
  341.                 new->q1.am=new->q2.am=new->z.am=0;
  342.                 first_ic=merk_fic;
  343.                 gen_label(m3);
  344.             }
  345.         }
  346.     }
  347.     switch_typ=merk_typ;switch_act=merk_count;break_label=merk_break;
  348.     if(tree) free_expression(tree);
  349.     cr();
  350. }
  351. void while_statement(void)
  352. /*  bearbeitet while_statement                                  */
  353. {
  354.     np tree;int lloop,lin,lout,cm,cexpr,contm,breakm;
  355.     struct IC *new;
  356.     killsp();
  357.     if(*s=='(') {s++;killsp();} else error(151);
  358.     tree=expression();
  359.     cexpr=0;
  360.     if(tree){
  361.         if(type_expression(tree)){
  362.             tree=makepointer(tree);
  363.             if(!arith(tree->ntyp->flags&15)&&(tree->ntyp->flags&15)!=POINTER){
  364.                 error(140);
  365.                 cexpr=-1;
  366.             }else{
  367.                 if(tree->flags==ASSIGN) error(164);
  368.                 if(tree->flags==CEXPR){
  369.                     eval_const(&tree->val,tree->ntyp->flags&31);
  370.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))) cexpr=1; else cexpr=2;
  371.                     if(cexpr==1) error(152);
  372.                 }
  373.             }
  374.         }else cexpr=-1;
  375.     } else error(141);
  376.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  377.     contm=cont_label;breakm=break_label;
  378.     if(!cexpr||tree->sidefx) cont_label=lin; else cont_label=lloop;
  379.     if(!cexpr||tree->sidefx){
  380.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  381.             gen_IC(tree,lloop,lout);
  382.             if(tree->o.flags){
  383.                 new=mymalloc(ICS);
  384.                 new->code=TEST;
  385.                 new->typf=tree->ntyp->flags&31;
  386.                 new->q1=tree->o;
  387.                 new->q2.flags=new->z.flags=0;
  388.                 add_IC(new);
  389.                 new=mymalloc(ICS);
  390.                 new->code=BEQ;
  391.                 new->typf=lout;
  392.                 add_IC(new);
  393.             }
  394.             if(!type_expression(tree)) ierror(0);
  395.         }else{
  396.             new=mymalloc(ICS);
  397.             new->code=BRA;
  398.             new->typf=lin;
  399.             add_IC(new);
  400.         }
  401.     }
  402.     if(cexpr==1){
  403.         new=mymalloc(ICS);
  404.         new->code=BRA;
  405.         new->typf=lout;
  406.         add_IC(new);
  407.     }else gen_label(lloop);
  408.     cm=nocode;break_label=lout;
  409.     if(cexpr==1) nocode=1;
  410.     currentpri*=looppri;
  411.     killsp();
  412.     if(*s==')') {s++;killsp();} else error(59);
  413.     statement();
  414.     nocode=cm;cont_label=contm;break_label=breakm;
  415.     if(!cexpr||tree->sidefx) gen_label(lin);
  416.     if(tree&&cexpr>=0){
  417.         if(cexpr!=1||tree->sidefx){
  418.             gen_IC(tree,lloop,lout);
  419.             if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  420.         }
  421.         if(tree->o.flags&&!cexpr){
  422.             new=mymalloc(ICS);
  423.             new->code=TEST;
  424.             new->typf=tree->ntyp->flags&31;
  425.             new->q1=tree->o;
  426.             new->q2.flags=new->z.flags=0;
  427.             add_IC(new);
  428.             new=mymalloc(ICS);
  429.             new->code=BNE;
  430.             new->typf=lloop;
  431.             add_IC(new);
  432.         }
  433.         if(cexpr==2){
  434.             new=mymalloc(ICS);
  435.             new->code=BRA;
  436.             new->typf=lloop;
  437.             add_IC(new);
  438.         }
  439.     }
  440.     if(tree) free_expression(tree);
  441.     gen_label(lout);
  442.     currentpri/=looppri;
  443.     cr();
  444. }
  445. void for_statement(void)
  446. /*  bearbeitet for_statement                                    */
  447. {
  448.     np tree1=0,tree2=0,tree3=0;int lloop,lin,lout,cm,cexpr,contm,breakm;
  449.     struct IC *new;
  450.     killsp();
  451.     if(*s=='(') {s++;killsp();} else error(59);
  452.     if(*s!=';') tree1=expression();
  453.     if(tree1){
  454.         if(tree1->flags==POSTINC) tree1->flags=PREINC;
  455.         if(tree1->flags==POSTDEC) tree1->flags=PREDEC;
  456.         if(type_expression(tree1)){
  457.             if(tree1->sidefx){
  458.                 gen_IC(tree1,0,0);
  459.                 if(tree1&&(tree1->o.flags&SCRATCH)) free_reg(tree1->o.reg);
  460.             }else{error(153);}
  461.         }
  462.         free_expression(tree1);
  463.     }
  464.     cexpr=0;
  465.     killsp();
  466.     if(*s==';') {s++;killsp();} else error(54);
  467.     if(*s!=';') {tree2=expression();killsp();} else {cexpr=2;}
  468.     if(*s==';') {s++;killsp();} else error(54);
  469.     if(*s!=')') tree3=expression();
  470.     killsp();
  471.     if(*s==')') {s++;killsp();} else error(59);
  472.     if(tree3){
  473.         if(!type_expression(tree3)){
  474.             free_expression(tree3);
  475.             tree3=0;
  476.         }
  477.     }
  478.     if(tree2){
  479.         if(type_expression(tree2)){
  480.             tree2=makepointer(tree2);
  481.             if(!arith(tree2->ntyp->flags&15)&&(tree2->ntyp->flags&15)!=POINTER){
  482.                 error(142);
  483.                 cexpr=-1;
  484.             }else{
  485.                 if(tree2->flags==ASSIGN) error(164);
  486.                 if(tree2->flags==CEXPR){
  487.                     eval_const(&tree2->val,tree2->ntyp->flags&31);
  488.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))) cexpr=1; else cexpr=2;
  489.                     if(cexpr==1) error(152);
  490.                 }
  491.             }
  492.         }else cexpr=-1;
  493.     }
  494.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  495.     contm=cont_label;breakm=break_label;
  496.     cont_label=++label;break_label=lout;
  497.     if(!cexpr||(tree2&&tree2->sidefx)){
  498.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  499.             gen_IC(tree2,lloop,lout);
  500.             if(tree2->o.flags){
  501.                 new=mymalloc(ICS);
  502.                 new->code=TEST;
  503.                 new->typf=tree2->ntyp->flags&31;
  504.                 new->q1=tree2->o;
  505.                 new->q2.flags=new->z.flags=0;
  506.                 add_IC(new);
  507.                 new=mymalloc(ICS);
  508.                 new->code=BEQ;
  509.                 new->typf=lout;
  510.                 add_IC(new);
  511.             }
  512.             if(!type_expression(tree2)) ierror(0);
  513.         }else{
  514.             new=mymalloc(ICS);
  515.             new->code=BRA;
  516.             new->typf=lin;
  517.             add_IC(new);
  518.         }
  519.     }
  520.     if(cexpr==1){
  521.         new=mymalloc(ICS);
  522.         new->code=BRA;
  523.         new->typf=lout;
  524.         add_IC(new);
  525.     }else gen_label(lloop);
  526.     cm=nocode;
  527.     if(cexpr==1) nocode=1;
  528.     currentpri*=looppri;
  529.     statement();
  530.     nocode=cm;
  531.     gen_label(cont_label);
  532.     cont_label=contm;break_label=breakm;
  533.     if(tree3){
  534.         if(tree3->flags==POSTINC) tree3->flags=PREINC;
  535.         if(tree3->flags==POSTDEC) tree3->flags=PREDEC;
  536.         if(tree3->sidefx){
  537.             gen_IC(tree3,0,0);
  538.             if(tree3&&(tree3->o.flags&SCRATCH)) free_reg(tree3->o.reg);
  539.         }else error(153);
  540.         free_expression(tree3);
  541.     }
  542.     if(!cexpr||(tree2&&tree2->sidefx)) gen_label(lin);
  543.     if(tree2&&cexpr>=0){
  544.         if(cexpr!=1||tree2->sidefx){
  545.             gen_IC(tree2,lloop,lout);
  546.             if((tree2->o.flags&SCRATCH)&&cexpr) free_reg(tree2->o.reg);
  547.         }
  548.         if(tree2->o.flags&&!cexpr){
  549.             new=mymalloc(ICS);
  550.             new->code=TEST;
  551.             new->typf=tree2->ntyp->flags&31;
  552.             new->q1=tree2->o;
  553.             new->q2.flags=new->z.flags=0;
  554.             add_IC(new);
  555.             new=mymalloc(ICS);
  556.             new->code=BNE;
  557.             new->typf=lloop;
  558.             add_IC(new);
  559.         }
  560.         if(cexpr==2){
  561.             new=mymalloc(ICS);
  562.             new->code=BRA;
  563.             new->typf=lloop;
  564.             add_IC(new);
  565.         }
  566.     }
  567.     if(!tree2&&cexpr==2){
  568.         new=mymalloc(ICS);
  569.         new->code=BRA;
  570.         new->typf=lloop;
  571.         add_IC(new);
  572.     }
  573.     if(tree2) free_expression(tree2);
  574.     gen_label(lout);
  575.     currentpri/=looppri;
  576.     cr();
  577. }
  578. void do_statement(void)
  579. /*  bearbeitet do_statement                                     */
  580. {
  581.     np tree;int lloop,lout,contm,breakm;
  582.     struct IC *new;
  583.     lloop=++label;lout=++label;currentpri*=looppri;
  584.     gen_label(lloop);
  585.     breakm=break_label;contm=cont_label;cont_label=++label;break_label=lout;
  586.     statement();
  587.     killsp();
  588.     gen_label(cont_label);cont_label=contm;break_label=breakm;
  589.     cpbez(buff,0);killsp();
  590.     if(strcmp("while",buff)) error(154);
  591.     if(*s=='(') {s++;killsp();} else error(151);
  592.     tree=expression();
  593.     if(tree){
  594.         if(type_expression(tree)){
  595.             tree=makepointer(tree);
  596.             if(arith(tree->ntyp->flags&15)||(tree->ntyp->flags&15)==POINTER){
  597.                 if(tree->flags==ASSIGN) error(164);
  598.                 if(tree->flags==CEXPR){
  599.                     eval_const(&tree->val,tree->ntyp->flags&31);
  600.                     if(tree->sidefx) gen_IC(tree,0,0);
  601.                     if(!zdeqto(vdouble,d2zd(0.0))){
  602.                         new=mymalloc(ICS);
  603.                         new->code=BRA;
  604.                         new->typf=lloop;
  605.                         add_IC(new);
  606.                     }
  607.                 }else{
  608.                     gen_IC(tree,lloop,lout);
  609.                     if(tree->o.flags){
  610.                         new=mymalloc(ICS);
  611.                         new->code=TEST;
  612.                         new->typf=tree->ntyp->flags&31;
  613.                         new->q1=tree->o;
  614.                         new->q2.flags=new->z.flags=0;
  615.                         add_IC(new);
  616.                         new=mymalloc(ICS);
  617.                         new->code=BNE;
  618.                         new->typf=lloop;
  619.                         add_IC(new);
  620.                     }
  621.                 }
  622.             }else error(143);
  623.         }
  624.         free_expression(tree);
  625.     }
  626.     killsp();
  627.     if(*s==')') {s++;killsp();} else error(59);
  628.     if(*s==';') {s++;killsp();} else error(54);
  629.     gen_label(lout);
  630.     currentpri/=looppri;
  631.     cr();
  632. }
  633. void goto_statement(void)
  634. /*  bearbeitet goto_statement                                   */
  635. {
  636.     struct llist *lp;
  637.     struct IC *new;
  638.     killsp();cpbez(buff,1);
  639.     if(!*buff) error(144);
  640.     lp=find_label(buff);
  641.     if(!lp) lp=add_label(buff);
  642.     lp->flags|=LABELUSED;
  643.     new=mymalloc(ICS);
  644.     new->typf=lp->label;
  645.     new->code=BRA;
  646.     new->typf=lp->label;
  647.     add_IC(new);
  648.     killsp();
  649.     if(*s==';'){s++;killsp();} else error(54);
  650.     cr();
  651.     goto_used=1;
  652. }
  653. void continue_statement(void)
  654. /*  bearbeitet continue_statement                               */
  655. {
  656.     struct IC *new;
  657.     if(cont_label==0){error(145);return;}
  658.     new=mymalloc(ICS);
  659.     new->code=BRA;
  660.     new->typf=cont_label;
  661.     add_IC(new);
  662.     killsp();
  663.     if(*s==';') {s++;killsp();} else error(54);
  664.     cr();
  665. }
  666. void break_statement(void)
  667. /*  bearbeitet break_statement                                  */
  668. {
  669.     struct IC *new;
  670.     if(break_label==0){error(146);return;}
  671.     new=mymalloc(ICS);
  672.     new->code=BRA;
  673.     new->typf=break_label;
  674.     add_IC(new);
  675.     killsp();
  676.     if(*s==';') {s++;killsp();} else error(54);
  677.     cr();
  678. }
  679. extern int has_return;
  680. void return_statement(void)
  681. /*  bearbeitet return_statement                                 */
  682. /*  SETRETURN hat Groesse in q2.reg und z.reg==freturn(rtyp)    */
  683. {
  684.     np tree;
  685.     struct IC *new;
  686.     has_return=1;
  687.     killsp();
  688.     if(*s!=';'){
  689.         if(tree=expression()){
  690.             if(!return_typ){
  691.                 if(type_expression(tree)){
  692.                     tree=makepointer(tree);
  693.                     if((tree->ntyp->flags&15)!=VOID)
  694.                         error(155);
  695.                     gen_IC(tree,0,0);
  696.                     if(tree->o.flags&SCRATCH) free_reg(tree->o.reg);
  697.                 }
  698.             }else{
  699.                 if(type_expression(tree)){
  700.                     tree=makepointer(tree);
  701.                     if(!test_assignment(return_typ,tree)){free_expression(tree);return;}
  702.                     gen_IC(tree,0,0);
  703.                     convert(tree,return_typ->flags&31);
  704. #ifdef OLDPARMS   /*  alte CALL/RETURN-Methode    */
  705.                     new=mymalloc(ICS);
  706.                     new->code=ASSIGN;
  707.                     new->typf=return_typ->flags&31;
  708.                     new->q1=tree->o;
  709.                     new->q2.flags=0;
  710.                     new->q2.val.vlong=szof(return_typ);
  711.                     if(freturn(return_typ)){
  712.                         new->z.flags=SCRATCH|REG;
  713.                         new->z.reg=freturn(return_typ);
  714.                         if(!regs[new->z.reg]){
  715.                             struct IC *alloc=mymalloc(ICS);
  716.                             alloc->code=ALLOCREG;
  717.                             alloc->q1.flags=REG;
  718.                             alloc->q2.flags=alloc->z.flags=0;
  719.                             alloc->q1.reg=new->z.reg;
  720.                             regs[new->z.reg]=1;
  721.                             add_IC(alloc);
  722.                         }
  723.                     }else{
  724.                         new->z.reg=0;
  725.                         new->z.v=return_var;
  726.                         new->z.flags=SCRATCH|VAR;
  727.                         new->z.val.vlong=l2zl(0L);
  728.                     }
  729.                     add_IC(new);
  730.                     /*  das hier ist nicht sehr schoen, aber wie sonst? */
  731.                     if(new->z.flags&SCRATCH&®s[new->z.reg]) free_reg(new->z.reg);
  732. #else
  733.                     new=mymalloc(ICS);
  734.                     if(return_var){ /*  Returnwert ueber Zeiger */
  735.                         new->code=ASSIGN;
  736.                         new->z.flags=VAR|DREFOBJ;
  737.                         new->z.val.vlong=l2zl(0L);
  738.                         new->z.v=return_var;
  739.                     }else{
  740.                         new->code=SETRETURN;
  741.                         new->z.reg=freturn(return_typ);
  742.                         new->z.flags=0;
  743.                     }
  744.                     new->typf=return_typ->flags&31;
  745.                     new->q1=tree->o;
  746.                     new->q2.flags=0;
  747.                     new->q2.val.vlong=szof(return_typ);
  748.                     add_IC(new);
  749. #endif
  750.                 }
  751.             }
  752.             free_expression(tree);
  753.             killsp();
  754.             if(*s==';') {s++;killsp();} else error(54);
  755.         }else{
  756.             if(return_typ) error(156);
  757.         }
  758.     }else{ s++; if(return_typ) error(156);}
  759.  
  760.     new=mymalloc(ICS);
  761.     new->code=BRA;
  762.     new->typf=return_label;
  763.     add_IC(new);
  764.     cr();
  765. }
  766.  
  767. void expression_statement(void)
  768. /*  bearbeitet expression_statement                             */
  769. {
  770.     np tree;
  771.     killsp();
  772.     if(*s==';') {s++;return;}
  773.     if(tree=expression()){
  774.         if(tree->flags==POSTINC) tree->flags=PREINC;
  775.         if(tree->flags==POSTDEC) tree->flags=PREDEC;
  776.         if(type_expression(tree)){
  777.             if(DEBUG&2){pre(stdout,tree);printf("\n");}
  778.             if(tree->sidefx){
  779.                 gen_IC(tree,0,0);
  780.                 if((tree->o.flags&(SCRATCH|REG))==REG) ierror(0);
  781.                 if(tree&&(tree->o.flags&SCRATCH)) free_reg(tree->o.reg);
  782.             }else{error(153);if(DEBUG&2) prd(stdout,tree->ntyp);}
  783.         }
  784.         free_expression(tree);
  785.     }
  786.     killsp();
  787.     if(*s==';') s++; else error(54);
  788.     cr();
  789. }
  790. void compound_statement(void)
  791. /*  bearbeitet compound_statement (block)                       */
  792. {
  793.     killsp();
  794.     if(*s=='{') s++; else error(157);
  795.     killsp();
  796.     while(declaration(0)){
  797.         var_declaration();
  798.         killsp();
  799.     }
  800.     while(*s!='}'){
  801.         statement();
  802.         killsp();
  803.     }
  804.     s++;/*killsp();*/
  805. }
  806. struct llist *add_label(char *identifier)
  807. /*  Fuegt label in Liste                                        */
  808. {
  809.     struct llist *new;
  810.     new=mymalloc(LSIZE);
  811.     new->next=0;new->label=++label;new->flags=0;
  812.     new->identifier=add_identifier(identifier,strlen(identifier));
  813.     if(first_llist==0){
  814.         first_llist=last_llist=new;
  815.     }else{
  816.         last_llist->next=new;
  817.         last_llist=new;
  818.     }
  819.     return(last_llist); /* return(new) sollte aequiv. sein */
  820. }
  821. struct llist *find_label(char *identifier)
  822. /*  Sucht Label, gibt Zeiger auf llist oder 0 beu Fehler zurueck    */
  823. {
  824.     struct llist *p;
  825.     p=first_llist;
  826.     while(p){
  827.         if(!strcmp(p->identifier,identifier)) return(p);
  828.         p=p->next;
  829.     }
  830.     return(0);
  831. }
  832. void free_llist(struct llist *p)
  833. /*  Gibt llist frei                                             */
  834. {
  835.     struct llist *merk;
  836.     while(p){
  837.         merk=p->next;
  838.         if(!(p->flags&LABELDEFINED)) error(147,p->identifier);
  839.         if(!(p->flags&LABELUSED)&&!p->switch_count) error(148,p->identifier);
  840.         free(p);
  841.         p=merk;
  842.     }
  843. }
  844.